package cn.superchart.module.user.service;

import cn.superchart.common.base.BaseUserDetails;
import cn.superchart.common.enums.StatusEnum;
import cn.superchart.common.utils.CacheContext;
import cn.superchart.common.utils.Checker;
import cn.superchart.module.auth.api.UserDetailsServiceApi;
import cn.superchart.module.menu.mapper.ScMenuMapper;
import cn.superchart.module.user.entity.ScUser;
import cn.superchart.module.user.mapper.ScUserMapper;
import com.alicp.jetcache.Cache;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ScUserDetailsService extends UserDetailsServiceApi {

    private final ScUserMapper scUserMapper;

    private final ScMenuMapper scMenuMapper;


    public ScUserDetailsService(PasswordEncoder passwordEncoder, ScUserMapper scUserMapper, ScMenuMapper scMenuMapper) {
        super(passwordEncoder);
        this.scUserMapper = scUserMapper;
        this.scMenuMapper = scMenuMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {
        ScUser scUser = scUserMapper.loadUserByUsername(account);
        if(Checker.BeNull(scUser)){
            return new BaseUserDetails(null,null,null, Lists.newArrayList());
        }
        boolean noLock = StatusEnum.SC_USER_STATUS_UNLOCK.getCode().equals(scUser.getUserStatus());
        List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<>();
        if(noLock){
            List<String> permissions =   scMenuMapper.getMenuPerms(scUser.getId(),null,false);
            if(Checker.BeNotEmpty(permissions)){
                permissions.forEach(permission->grantedAuthorities.add(new SimpleGrantedAuthority(permission)));
            }
        }
        CacheContext.putAuthCache(scUser.getId(),grantedAuthorities);
        BaseUserDetails baseUserDetails = new BaseUserDetails(scUser.getAccount(),scUser.getPassword(),scUser.getId(), grantedAuthorities);
        baseUserDetails.setNoLocked(noLock);
        return baseUserDetails;
    }
}
